using System;
using LFromeWork;
using UnityEngine;
using Object = UnityEngine.Object;

namespace LFromeWork
{
    public class AssetRefEntity
    {
        /// <summary>
        /// 资源完整路径，包含后缀名
        /// </summary>
        public string AssetFullPath;

        /// <summary>
        /// asset加载完成
        /// </summary>
        public Action<string, Object> OnLoadAssetComplete;

        /// <summary>
        /// 资源加载请求
        /// </summary>
        public AssetBundleRequest CurrAssetBundleRequest { get; private set; }


        /// <summary>
        /// 关联目标
        /// </summary>
        public Object Target;

        /// <summary>
        /// 资源释放时间
        /// </summary>
        public float ReleaseTime { get; private set; }

        /// <summary>
        /// 引用计数
        /// </summary>
        public int ReferenceCount { get; private set; }

        /// <summary>
        /// 刷新最后使用时间
        /// </summary>
        public void RefreshReleaseTime()
        {
            ReleaseTime = Time.time + GameLaunch.ParamsSettings.PoolReleaseAssetInterval;
        }

        /// <summary>
        /// 引用计数+1
        /// </summary>
        public void ReferenceAdd()
        {
            ReferenceCount++;
        }

        /// <summary>
        /// 引用计数-1
        /// </summary>
        public void ReferenceRemove()
        {
            ReferenceCount--;
            if (ReferenceCount == 0)
                RefreshReleaseTime();

            if (ReferenceCount < 0)
            {
                GameLaunch.LogError("Asset引用计数出错， ReferenceCount==" + ReferenceCount);
            }
        }

        /// <summary>
        /// 对象是否可以释放
        /// </summary>
        /// <returns></returns>
        public bool GetCanRelease()
        {
            return ReferenceCount == 0 && Time.time >= ReleaseTime && Target != null;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Release()
        {
#if EDITORLOAD && UNITY_EDITOR
#else
            AssetBundleDepRemove();
#endif
            AssetFullPath = null;
            Target = null;
            GameLaunch.Pool.CoPool.Enqueue(this);
        }

        /// <summary>
        /// 释放asset 依赖的 assetbundle
        /// </summary>
        private void AssetBundleDepRemove()
        {
            AssetInfoEntity assetEntity = GameLaunch.Resources.AssetInfo.GetAssetEntity(AssetFullPath);
            GameLaunch.Resources.AssetBundleLoader.ReleaseAssetBundle(assetEntity.AssetBundleFullPath);

            for (int i = 0; i < assetEntity.DependsAssetBundleList.Count; i++)
                GameLaunch.Resources.AssetBundleLoader.ReleaseAssetBundle(assetEntity.DependsAssetBundleList[i]);
        }

        public static AssetRefEntity Create(string assetFullPath)
        {
            AssetRefEntity referenceEntity = GameLaunch.Pool.CoPool.Dequeue<AssetRefEntity>();
            referenceEntity.AssetFullPath = assetFullPath;

            return referenceEntity;
        }

        internal void LoadAssetAsync(AssetBundle assetBundle)
        {
            if (assetBundle == null) return;
            CurrAssetBundleRequest = assetBundle.LoadAssetAsync(AssetFullPath);
        }

        /// <summary>
        /// 更新 资源加载 请求
        /// </summary>
        public void UpdateAssetBundleRequest()
        {
            if (CurrAssetBundleRequest != null)
            {
                if (CurrAssetBundleRequest.isDone)
                {
                    Target = CurrAssetBundleRequest.asset;
                    if (Target == null)
                        GameLaunch.LogError("资源加载失败 => " + AssetFullPath);

                    OnLoadAssetComplete?.Invoke(AssetFullPath, Target);

                    OnLoadAssetComplete = null;
                    CurrAssetBundleRequest = null;
                }
            }
        }
    }
}
